/**
 * 
 */
package com.star.util.file;

import java.io.BufferedInputStream;
import java.io.BufferedOutputStream;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import java.util.ArrayList;
import java.util.Enumeration;
import java.util.List;

import javax.servlet.http.HttpServletResponse;

import org.apache.tools.zip.ZipEntry;
import org.apache.tools.zip.ZipFile;
import org.apache.tools.zip.ZipOutputStream;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import com.alibaba.druid.stat.TableStat.Name;

/**
 * @ClassName: FileUtil
 * @Description: TODO
 * @author starhq
 * @createtime 2014年10月23日 下午3:27:38
 * @email : jian.wang@shinsoft.net
 * @modify by TODO
 * @resaon
 * @edittime
 * @version 1.0
 * @copyright shinsoft
 */
public class FileUtil {
	private static Logger log = LoggerFactory.getLogger(FileUtil.class);

	/**
	 * 
	 * 压缩文件
	 * 
	 * @param inputFileName
	 *            要压缩的文件或文件夹路径，例如：c:\\a.txt,c:\\a\
	 * 
	 * @param outputFileName
	 *            输出zip文件的路径，例如：c:\\a.zip
	 * 
	 */
	public static void zip(String inputFileName, String outputFileName)
			throws Exception {
		ZipOutputStream out = new ZipOutputStream(new FileOutputStream(
				outputFileName));

		zip(out, new File(inputFileName), "");

		log.debug("压缩完成！");

		out.closeEntry();

		out.close();
	}

	/**
	 * 
	 * 压缩文件
	 * 
	 * @param out
	 *            org.apache.tools.zip.ZipOutputStream
	 * 
	 * @param file
	 *            待压缩的文件
	 * 
	 * @param base
	 *            压缩的根目录
	 * 
	 */
	public static void zip(ZipOutputStream out, File file, String base)
			throws Exception {

		if (file.isDirectory()) {
			File[] f1 = file.listFiles();

			base = base.length() == 0 ? "" : base + File.separator;

			for (int i = 0; i < f1.length; i++) {
				zip(out, f1[i], base + f1[i].getName());
			}
		} else {
			out.putNextEntry(new ZipEntry(base));

			log.debug("添加压缩文件: " + base);

			InputStream in = new FileInputStream(file);

			int b;

			byte[] buff = new byte[1024];

			while ((b = in.read(buff)) != -1) {

				out.write(buff, 0, b);

			}

			in.close();
		}

	}

	/**
	 * 
	 * 解压zip文件
	 * 
	 * @param zipFileName
	 *            待解压的zip文件路径，例如：c:\\a.zip
	 * 
	 * @param outputDirectory
	 *            解压目标文件夹,例如：c:\\a\
	 * 
	 */
	public static void unZip(String zipFileName, String outputDirectory)
			throws Exception {

		ZipFile zipFile = new ZipFile(zipFileName);

		try {
			Enumeration<?> e = zipFile.getEntries();

			ZipEntry zipEntry = null;

			createDirectory(outputDirectory, "");

			while (e.hasMoreElements()) {
				zipEntry = (ZipEntry) e.nextElement();

				log.debug("解压：" + zipEntry.getName());

				if (zipEntry.isDirectory()) {

					String name = zipEntry.getName();

					name = name.substring(0, name.length() - 1);

					File f = new File(outputDirectory + File.separator + name);

					f.mkdir();

					log.debug("创建目录：" + outputDirectory + File.separator + name);

				} else {

					String fileName = zipEntry.getName();

					fileName = fileName.replace('\\', '/');

					if (fileName.indexOf("/") != -1) {

						createDirectory(outputDirectory, fileName.substring(0,
								fileName.lastIndexOf("/")));

						fileName = fileName.substring(
								fileName.lastIndexOf("/") + 1,
								fileName.length());

					}

					File f = new File(outputDirectory + File.separator
							+ zipEntry.getName());

					f.createNewFile();

					InputStream in = zipFile.getInputStream(zipEntry);

					FileOutputStream out = new FileOutputStream(f);

					byte[] by = new byte[1024];

					int c;

					while ((c = in.read(by)) != -1) {

						out.write(by, 0, c);

					}

					in.close();

					out.close();

				}

			}

		} catch (Exception ex) {

			log.error("解压失败: " + ex.getMessage());

		} finally {
			zipFile.close();

			log.debug("解压完成！");
		}
	}

	private static void createDirectory(String directory, String subDirectory) {

		String dir[];

		File fl = new File(directory);

		try {

			if (subDirectory == "" && fl.exists() != true) {

				fl.mkdir();

			} else if (subDirectory != "") {

				dir = subDirectory.replace('\\', '/').split("/");

				for (int i = 0; i < dir.length; i++) {

					File subFile = new File(directory + File.separator + dir[i]);

					if (subFile.exists() == false)

						subFile.mkdir();

					directory += File.separator + dir[i];

				}

			}

		} catch (Exception ex) {

			log.error("创建文件夹失败: " + ex.getMessage());

		}
	}

	/**
	 * 
	 * 拷贝文件夹中的所有文件到另外一个文件夹
	 * 
	 * @param srcDirector
	 *            源文件夹
	 * 
	 * @param desDirector
	 *            目标文件夹
	 * 
	 */

	public static void copyFileWithDirector(String srcDirector,
			String desDirector) throws IOException {

		(new File(desDirector)).mkdirs();

		File[] file = (new File(srcDirector)).listFiles();

		for (int i = 0; i < file.length; i++) {

			if (file[i].isFile()) {

				log.debug("拷贝：" + file[i].getAbsolutePath() + "-->"
						+ desDirector + "/" + file[i].getName());

				FileInputStream input = new FileInputStream(file[i]);

				FileOutputStream output = new FileOutputStream(desDirector
						+ "/" + file[i].getName());

				byte[] b = new byte[1024 * 5];

				int len;

				while ((len = input.read(b)) != -1) {

					output.write(b, 0, len);

				}

				output.flush();

				output.close();

				input.close();

			}

			if (file[i].isDirectory()) {

				log.debug("拷贝：" + file[i].getAbsolutePath() + "-->"
						+ desDirector + "/" + file[i].getName());

				copyFileWithDirector(srcDirector + "/" + file[i].getName(),
						desDirector + "/" + file[i].getName());

			}

		}

	}

	/**
	 * 
	 * 删除文件夹
	 * 
	 * @param folderPath
	 *            folderPath 文件夹完整绝对路径
	 * 
	 */

	public static void delFolder(String folderPath) throws Exception {

		// 删除完里面所有内容

		delAllFile(folderPath);

		String filePath = folderPath;

		filePath = filePath.toString();

		File myFilePath = new File(filePath);

		// 删除空文件夹

		myFilePath.delete();

	}

	/**
	 * 
	 * 删除指定文件夹下所有文件
	 * 
	 * @param path
	 *            文件夹完整绝对路径
	 * 
	 */

	public static boolean delAllFile(String path) throws Exception {

		boolean flag = false;

		File file = new File(path);

		if (!file.exists()) {

			return flag;

		}

		if (!file.isDirectory()) {

			return flag;

		}

		String[] tempList = file.list();

		File temp = null;

		for (int i = 0; i < tempList.length; i++) {

			if (path.endsWith(File.separator)) {

				temp = new File(path + tempList[i]);

			} else {

				temp = new File(path + File.separator + tempList[i]);

			}

			if (temp.isFile()) {

				temp.delete();

			}

			if (temp.isDirectory()) {

				// 先删除文件夹里面的文件

				delAllFile(path + "/" + tempList[i]);

				// 再删除空文件夹

				delFolder(path + "/" + tempList[i]);

				flag = true;

			}

		}

		return flag;

	}

	public static void makeStreamFile(File file, HttpServletResponse response) {
		OutputStream os = null;
		BufferedOutputStream output = null;
		BufferedInputStream input = null;

		try {

			response.reset();

			os = response.getOutputStream();

			response.setHeader("Content-disposition", "attachment; filename="
					+ new String(file.getName().getBytes("ISO-8859-1"),
							"ISO-8859-1"));

			response.setContentType("application/x-download");

			response.setContentLength((int) file.length());

			byte[] buffer = new byte[4096];
			output = new BufferedOutputStream(os);
			input = new BufferedInputStream(new FileInputStream(file));
			int n = (-1);
			while ((n = input.read(buffer, 0, 4096)) > -1) {
				output.write(buffer, 0, n);
				response.flushBuffer();
			}
		} catch (IOException e) {
			log.error("生成下载流失败: " + e.getMessage());
		} finally {
			if (input != null)
				try {
					input.close();
				} catch (IOException e) {
					e.printStackTrace();
				}
			if (output != null)
				try {
					output.close();
				} catch (IOException e) {
					e.printStackTrace();
				}
		}
	}

	/**
	 * 获得文件的扩展名
	 * 
	 * @param fileName
	 *            文件名
	 * @return 扩展名
	 */
	public static String getExtension(String fileName) {
		if (fileName == null) {
			return null;
		}
		int index = fileName.lastIndexOf(".");
		if (index == -1) {
			return "";
		} else {
			String ext = fileName.substring(index + 1);
			return (ext.contains("/") || ext.contains("\\")) ? "" : ext;
		}
	}

}
